package com.guigu.eduservice.controller;

import com.guigu.eduservice.config.AliPayConfig;
import com.guigu.eduservice.entity.Order;
import com.guigu.eduservice.service.EquipmentReservationService;
import com.guigu.eduservice.service.EquipmentService;
import com.guigu.eduservice.service.OrderService;
import com.guigu.eduservice.util.AlipaySandboxUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/eduservice/alipay")
public class AlipayController {

    // 注入支付工具类（核心逻辑都在工具类中）
    @Resource
    private AlipaySandboxUtil alipaySandboxUtil;

    // 注入业务服务
    @Resource
    private EquipmentReservationService equipmentReservationService;
    @Autowired
    private OrderService ordersService;
    @Autowired
    private EquipmentService equipmentService;

    /**
     * 发起支付请求
     * 前端调用此接口，获取支付表单并跳转支付宝
     */
    @GetMapping("/pay")//前端只需要window.open = `http://你的后端域名/eduservice/alipay/pay?orderId=${orderId}`;
    public void pay(String orderId, HttpServletResponse response) throws IOException {
        System.out.println("发起支付，订单ID：" + orderId);

        // 1. 校验订单ID非空且长度（关键修复：限制订单号长度≤32位，添加前缀避免纯数字）
        if (orderId == null || orderId.trim().isEmpty() || orderId.length() > 32) {
            response.getWriter().write("订单ID格式错误");
            return;
        }
        // 关键：给订单号添加前缀，避免纯数字格式（支付宝沙箱对纯数字订单号校验更严格）
        String outTradeNo = "CAR_" + orderId;

        // 2. 校验订单是否存在
        Order order = ordersService.getById(orderId);
        if (order == null) {
            response.getWriter().write("订单不存在");
            return;
        }

        // 3. 防止重复支付（状态3表示已支付尾款）
        if (order.getOrderStatus() == 3) {
            response.getWriter().write("该订单已支付尾款");
            return;
        }

        // 4. 校验尾款金额非空且大于0
        if (order.getBalanceAmount() == null || order.getBalanceAmount().compareTo(BigDecimal.ZERO) <= 0) {
            response.getWriter().write("尾款金额异常，请重新下单");
            return;
        }

        // 5. 关键修复：使用BigDecimal原生方法格式化金额（避免浮点精度丢失）
        String totalAmount = order.getBalanceAmount().setScale(2, BigDecimal.ROUND_HALF_UP).toString();

        // 6. 订单标题优化（简洁且符合支付宝要求，避免特殊字符）
        String subject = "车辆尾款支付";

        System.out.println("支付参数：outTradeNo=" + outTradeNo + ", totalAmount=" + totalAmount + ", subject=" + subject);

        // 7. 调用工具类生成支付表单（传入处理后的订单号）
        String payForm = alipaySandboxUtil.createPayForm(
                outTradeNo,                // 处理后的订单号（带前缀）
                totalAmount,               // 原生格式化的金额
                subject                    // 简洁标题
        );

        // 8. 输出表单到前端
        response.setContentType("text/html;charset=" + AliPayConfig.CHARSET);
        response.getWriter().write(payForm);
        response.getWriter().flush();
        response.getWriter().close();
    }
    /**
     * 支付宝异步回调接口
     * 支付完成后，支付宝会自动调用此接口通知支付结果
     * 处理支付尾款接口
     */
    /**
     * 支付宝异步回调接口
     * 支付完成后，支付宝会自动调用此接口通知支付结果
     * 处理支付尾款接口
     */
    @PostMapping("/notify")
    public void payNotify(HttpServletRequest request) {
        try {
            // 1. 解析回调参数
            Map<String, String> params = new HashMap<>();
            Map<String, String[]> requestParams = request.getParameterMap();
            for (String key : requestParams.keySet()) {
                // 将参数转为字符串（支付宝回调参数是数组，取第一个值）
                params.put(key, request.getParameter(key));
            }

            // 2. 验证签名（防止虚假回调）
            boolean signValid = alipaySandboxUtil.verifySign(params);
            if (!signValid) {
                System.out.println("签名验证失败，可能是虚假请求，参数：" + params);
                return;
            }

            // 3. 校验支付状态（只有TRADE_SUCCESS表示支付成功）
            String tradeStatus = params.get("trade_status");
            if (!"TRADE_SUCCESS".equals(tradeStatus)) {
                System.out.println("支付状态异常：" + tradeStatus + "，订单号：" + params.get("out_trade_no"));
                return;
            }

            // 4. 关键修复1：获取带前缀的订单号，还原为原始订单号（去掉CAR_前缀）
            String outTradeNo = params.get("out_trade_no"); // 格式：CAR_1761873928711
            String originalOrderId = outTradeNo.replace("CAR_", ""); // 还原为：1761873928711
            String alipayTradeNo = params.get("trade_no");

            System.out.println("支付成功，带前缀订单号：" + outTradeNo + "，原始订单号：" + originalOrderId + "，支付宝交易号：" + alipayTradeNo);

            // 5. 关键修复2：用原始订单号查询并更新订单（数据库中存储的是原始订单号）
            // 先查询订单是否存在，避免空指针
            Order order = ordersService.getById(originalOrderId);
            if (order == null) {
                System.out.println("订单不存在，原始订单号：" + originalOrderId);
                return;
            }

            // 6. 防止重复更新（如果已更新过状态，直接返回）
            if (order.getOrderStatus() == 3) {
                System.out.println("订单已更新为已支付尾款状态，无需重复处理，原始订单号：" + originalOrderId);
                return;
            }

            // 6.1 更新订单表（用原始订单号匹配）
            boolean orderUpdateSuccess = ordersService.update()
                    .eq("order_id", originalOrderId)
                    .set("balance_pay_time", LocalDateTime.now())
                    .set("order_status", 3) // 改为已支付尾款
                    .set("update_time", LocalDateTime.now())
                    .set("payment_method", "支付宝")
                    .update();

            System.out.println("订单状态更新结果：" + (orderUpdateSuccess ? "成功" : "失败") + "，原始订单号：" + originalOrderId);

            // 6.2 更新预定表（order对象是查询出来的，包含buyerId、equipmentId等信息）
            equipmentReservationService.update()
                    .eq("user_id", order.getBuyerId())
                    .eq("equipment_id", order.getEquipmentId())
                    .eq("reservation_status", 1)
                    .set("reservation_status", 2)
                    .set("order_id", originalOrderId) // 存储原始订单号
                    .set("deposit_pay_time", LocalDateTime.now())
                    .update();

            // 6.3 更新设备表
            equipmentService.update()
                    .eq("equipment_id", order.getEquipmentId())
                    .set("status", 3) // 改为已成交
                    .update();

            System.out.println("回调处理完成，原始订单号：" + originalOrderId);

        } catch (Exception e) {
            System.err.println("回调处理失败：" + e.getMessage());
            e.printStackTrace(); // 打印完整异常栈，便于排查
        }
    }
}
